﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;

namespace WFExtended.Framework.ServiceModel
{
    /// <summary>
    /// Extended Channel Factory
    /// </summary>
    /// <typeparam name="T">Service Contract</typeparam>
    public class ExtendedChannelFactory<T> : ChannelFactory<T>, IExtendedChannel
         where T : class
    {
        private int _retryCount;

        private TimeSpan _retryDelay;

        /// <summary>
        /// Initializes a new instance of the <see cref="ExtendedChannelFactory{T}"/> class.
        /// </summary>
        /// <param name="endpointConfigurationName">Name of the endpoint configuration.</param>
        /// <param name="retryCount">The retry count.</param>
        /// <param name="retryDelay">The retry delay.</param>
        public ExtendedChannelFactory(string endpointConfigurationName, int retryCount, TimeSpan retryDelay)
            : base(endpointConfigurationName)
        {
            _retryCount = retryCount;
            _retryDelay = retryDelay;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ExtendedChannelFactory{T}"/> class.
        /// </summary>
        /// <param name="ep">The ep.</param>
        /// <param name="retryCount">The retry count.</param>
        /// <param name="retryDelay">The retry delay.</param>
        public ExtendedChannelFactory(ServiceEndpoint ep, int retryCount, TimeSpan retryDelay)
            : base(ep)
        {
            _retryCount = retryCount;
            _retryDelay = retryDelay;
        }

        private ExtendedProxy<T> _extendedProxy;


        /// <summary>
        /// Creates the channel.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <param name="via">The via.</param>
        /// <returns></returns>
        public override T CreateChannel(EndpointAddress address, Uri via)
        {
            _extendedProxy = 
                new ExtendedProxy<T>(typeof(T), new ChannelFactory<T>(Endpoint).CreateChannel(address), this, _retryCount, _retryDelay);
            
            T proxy = (T)_extendedProxy.GetTransparentProxy();
            return proxy;
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (_extendedProxy != null)
                _extendedProxy.Close();

            _extendedProxy = null;

        }

    }
}
